package com.example.bbs.service.impl;

import com.example.bbs.domain.entity.Message;
import com.example.bbs.domain.entity.Notice;
import com.example.bbs.domain.entity.User;
import com.example.bbs.domain.model.CommentDTO;
import com.example.bbs.domain.model.NoticeResponse;
import com.example.bbs.domain.model.PostDTO;
import com.example.bbs.mapper.MessageMapper;
import com.example.bbs.util.ConstantUtil;
import com.example.bbs.util.HostHold;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 通知（点赞，评论，关注）
 */

@Service
public class NoticeService {

    @Resource
    private MessageMapper messageMapper;
    @Autowired
    private PostServiceImpl postServiceImpl;
    @Autowired
    private CommentServiceImpl commentServiceImpl;
    @Resource
    private RedisTemplate commentInfoRedisTemplate;

    /**
     * 查询所有种类的未读通知数量（可建立索引优化）
     * @return
     */
    public Integer getUnReadNoticeCount() {
        int count = 0;
        User user = HostHold.get();
        Set<String> keys = commentInfoRedisTemplate.keys("*");

        for (String key : keys) {
            CommentDTO commentDTO = commentServiceImpl.getCommentDTO(key);
            if (commentDTO.getComment().getHasRead() == ConstantUtil.NOTICE_STATUS_UNREAD) {
                PostDTO postDTO = postServiceImpl.getPostDTO(commentDTO.getComment().getPostId());
                if (postDTO.getUser().getUserId().equals(user.getUserId())) {
                    ++count;
                }
            }
        }
        return count;
    }

    /**
     * 添加评论通知
     * @param commentSn
     */
    public void addCommentNotice(String commentSn) {
        CommentDTO commentDTO = commentServiceImpl.getCommentDTO(commentSn);
        PostDTO postDTO = postServiceImpl.getPostDTO(commentDTO.getComment().getPostId());

        Message message = new Message();
        message.setFromUserAccountId(commentDTO.getUser().getUserId());
        message.setStatus("success");
        message.setToUserAccountId(postDTO.getUser().getUserId());
        message.setContent("评论帖子");
        message.setPostSn(postDTO.getPost().getPostId());
        messageMapper.insert(message);
    }


    /**
     * 查询评论通知列表
     * @param page
     * @param limit
     * @return
     */
    public NoticeResponse getCommentNotices(Integer page, Integer limit) {
        NoticeResponse noticeResponse = new NoticeResponse();
        List<Notice> noticeList = new ArrayList<>();

        User user = HostHold.get();

        Set<String> keys = commentInfoRedisTemplate.keys("*");
        keys.forEach(e -> {

            CommentDTO commentDTO = commentServiceImpl.getCommentDTO(e);
            PostDTO postDTO = postServiceImpl.getPostDTO(commentDTO.getComment().getPostId());
            User postUser = postDTO.getUser();
            if (postUser.getUserId().equals(user.getUserId())) {
                Notice notice = new Notice();
                notice.setCommentDTO(commentDTO);
                notice.setPost(postDTO.getPost());
                noticeList.add(notice);
            }

        });

        int totalSize = noticeList.size();
        if (totalSize == 0) {
            return noticeResponse;
        }
        //按时间倒序排序
        noticeList.sort((a, b) -> (int) (b.getCommentDTO().getComment().getCreateTime().getTime() -
                        a.getCommentDTO().getComment().getCreateTime().getTime()));
        //分页
        int start = page * limit - limit;
        int end = start + limit;
        if (end > totalSize) {
            end = totalSize;
        }

        List<Notice> subList = noticeList.subList(start, end);

        //设置已读
        setRead(subList);
        noticeResponse.setNoticeList(subList);
        noticeResponse.setTotalSize(totalSize);
        return noticeResponse;
    }

    private void setRead(List<Notice> noticeList) {
        noticeList.forEach(e -> {
            commentInfoRedisTemplate.opsForHash().put(e.getCommentDTO().getComment().getCommentId(),
                    "hasRead", ConstantUtil.NOTICE_STATUS_READ);
        });

    }

}
